package com.doupi.partner.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.impl.DefaultClaims;
import io.jsonwebtoken.impl.DefaultJwsHeader;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;

import java.io.FileInputStream;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.util.Date;
import java.util.Enumeration;
import java.util.Map;

/**
 * 用于生成数据token JWT工具
 */
public class JwtUtils {
	private final static Logger LOGGER = LoggerFactory.getLogger(JwtUtils.class);
	private static PrivateKey PRIVATE_KEY = null;
	private final static String JWT_DATA = "JWT_DATA";
	private static boolean IS_INIT = false;

	public JwtUtils(String secrectFile, String password) {
		try {
			InputStream in_cert;
			Resource resource = SpringContextUtils.getApplicationContext().getResource(secrectFile);
			if (null != resource) {
				in_cert = resource.getInputStream();
			} else {
				in_cert = new FileInputStream(secrectFile);
			}

			KeyStore myStore = KeyStore.getInstance("PKCS12");
			myStore.load(in_cert, password.toCharArray());
			Enumeration<String> objEnumeration = myStore.aliases();
			while (objEnumeration.hasMoreElements()) {
				String alias = objEnumeration.nextElement();
				PRIVATE_KEY = (PrivateKey) myStore.getKey(alias, password.toCharArray());
			}
			IS_INIT = true;
		} catch (Throwable e) {
			LOGGER.error("获取JWT私钥失败", e);
		}
	}

	public String generater(Object object) {
		if (IS_INIT) {
			DefaultJwsHeader jwsHeader = new DefaultJwsHeader();
			jwsHeader.setType("JWT");
			jwsHeader.setAlgorithm("RS256");
			Date issuedDate = new Date();
			DefaultClaims claims = new DefaultClaims();
			claims.setIssuer("bangle.pub");
			claims.setIssuedAt(issuedDate);
			claims.setExpiration(DateUtils.addDays(issuedDate, 30)); // 保存30天
			claims.put(JWT_DATA, object);
			return Jwts.builder().setHeader((Map<String, Object>) jwsHeader).setClaims(claims).signWith(SignatureAlgorithm.RS256, PRIVATE_KEY).compact();
		}
		return null;
	}

	public Object parse(String jwt) {
		if (IS_INIT) {
			Jws<Claims> parseClaim = Jwts.parser().setSigningKey(PRIVATE_KEY).parseClaimsJws(jwt);
			return parseClaim.getBody().get(JWT_DATA);
		}
		return null;
	}
}
